#include "FillDescParser.h"

#include "FillPropertyParser.h"
#include "ColorGroupParser.h"
#include "DoubleParser.h"

#include <QXmlStreamReader>
#include <QString>

namespace Ipc2581b
{

FillDescParser::FillDescParser(
    FillPropertyParser *&_fillPropertyParser
    , DoubleParser *&_lineWidthParser
    , DoubleParser *&_pitch1Parser
    , DoubleParser *&_pitch2Parser
    , DoubleParser *&_angle1Parser
    , DoubleParser *&_angle2Parser
    , ColorGroupParser *&_colorParser
):    m_fillPropertyParser(_fillPropertyParser)
    , m_lineWidthParser(_lineWidthParser)
    , m_pitch1Parser(_pitch1Parser)
    , m_pitch2Parser(_pitch2Parser)
    , m_angle1Parser(_angle1Parser)
    , m_angle2Parser(_angle2Parser)
    , m_colorParser(_colorParser)
{

}

bool FillDescParser::parse(QXmlStreamReader *reader)
{
    /* Pre */

    m_result.reset(new FillDesc());

    /* Attributes */

    QStringRef data;
    if (reader->attributes().hasAttribute(QStringLiteral("fillProperty")))
    {
        data = reader->attributes().value(QStringLiteral("fillProperty"));
        if (!m_fillPropertyParser->parse(reader, data))
            return false;
        m_result->fillProperty = m_fillPropertyParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("fillProperty: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("lineWidth")))
    {
        data = reader->attributes().value(QStringLiteral("lineWidth"));
        if (!m_lineWidthParser->parse(reader, data))
            return false;
        m_result->lineWidthOptional = Optional<Double>(m_lineWidthParser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("pitch1")))
    {
        data = reader->attributes().value(QStringLiteral("pitch1"));
        if (!m_pitch1Parser->parse(reader, data))
            return false;
        m_result->pitch1Optional = Optional<Double>(m_pitch1Parser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("pitch2")))
    {
        data = reader->attributes().value(QStringLiteral("pitch2"));
        if (!m_pitch2Parser->parse(reader, data))
            return false;
        m_result->pitch2Optional = Optional<Double>(m_pitch2Parser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("angle1")))
    {
        data = reader->attributes().value(QStringLiteral("angle1"));
        if (!m_angle1Parser->parse(reader, data))
            return false;
        m_result->angle1Optional = Optional<Double>(m_angle1Parser->result());
    }
    if (reader->attributes().hasAttribute(QStringLiteral("angle2")))
    {
        data = reader->attributes().value(QStringLiteral("angle2"));
        if (!m_angle2Parser->parse(reader, data))
            return false;
        m_result->angle2Optional = Optional<Double>(m_angle2Parser->result());
    }

    /* Elements */

    while (reader->readNextStartElement())
    {
        auto name = reader->name();
        if (m_colorParser->isSubstitution(name))
        {
            if (!m_colorParser->parse(reader))
                return false;
            auto result = m_colorParser->result();
            m_result->colorOptional = Optional<ColorGroup*>(result);
        }
        else
            reader->skipCurrentElement();
    }

    /* Post */

    // TODO: Check multiplicity of elements/attributes

    return true;
}

FillDesc *FillDescParser::result()
{
    return m_result.take();
}

}